<template>
    <div class="dpa-header">
        <!--logo-->
        <div class="logo"> <img :src="dpaLogo" /> </div>
        <div class="ver"></div>
        <!--标题-->
        <div class="center-area">
            <!--组织架构-->
            <div class="organizational" v-if="departmentShow" :title="selectedLabels">
                <a-tree-select
                    v-model:value="departmentId"
                    :tree-data="treeData"
                    :fieldNames="replaceFields"
                    :tree-default-expand-all="true"
                    :virtual="false"
                    :max-tag-count="2"
                    :multiple="isMultiple"
                    :tree-checkable="isMultiple"
                    :show-checked-strategy="SHOW_PARENT"
                    :treeNodeFilterProp="treeNodeFilterProp"
                    :get-popup-container="triggerNode => triggerNode.parentNode"
                >
                    <template #suffixIcon>
                        <caret-down-outlined />
                    </template>
                </a-tree-select>
            </div>
        </div>
        <div v-if="showTitle" class="title" :style="titleStyles">
            {{ titleStyle.title }}
        </div>
        <div class="config">
            <!--用户-->
            <div class="userinfo">
                <user-info :popup-container="popupContainer" :dropdown-icon="dropdownIcon">
                    <template #prefixIcon> <img :src="userImg" class="prefix-icon" alt="" /> </template>
                </user-info>
            </div>
            <!--时间-->
            <div class="time"> <img :src="systemTimeImg" class="system-time-icon" alt="" /> {{ time }} </div>
        </div>
    </div>
</template>

<script lang="ts">
    import useAlLayoutEffect from '../../../hooks/alLayoutEffect'
    import { defineComponent, computed, watch, ref } from 'vue'
    import UserInfo from './UserInfo.vue'
    import userImg from '@/assets/images/user.png'
    import systemTimeImg from '@/assets/images/system-time.png'
    import { getStorageByKey } from '@/utils/common'
    import { CURRENT_TIME } from '@/enums/cacheEnum'
    import { layoutProps } from '../props'
    import { useUserStore } from '@/store/modules/user'
    import Logo from '@/assets/logo.png'
    import dayjs from 'dayjs'
    import { TreeSelect } from 'ant-design-vue'
    import * as axios from '@/utils/http/Axios'
    import { get, cloneDeep } from 'lodash-es'
    import { isArray, isObject, isEmpty, isNullOrUnDef } from '@/utils/is'
    import { parseJson } from '@/utils/common'

    interface DepartmentInfo {
        id?: number
        [key: string]: any
    }

    export default defineComponent({
        name: 'DpaHeader',
        components: {
            UserInfo
        },
        props: {
            portalConfiguration: {
                type: Object,
                default: () => ({})
            },
            ...layoutProps
        },
        setup(props) {
            // ---------------------------------------------------- 属性
            const { showTitle, titleStyles } = useAlLayoutEffect(props)
            const SHOW_PARENT = TreeSelect.SHOW_PARENT
            const time = ref('') // 后面接口获取
            const dpaHeaderSetting = ref(props.portalConfiguration)
            const departmentInfo = ref<DepartmentInfo>({})
            const userStore = useUserStore()
            const popupContainer = 'parentNode'
            const dropdownIcon = 'down-outlined' // DPA导航下拉图标线性倒三角
            const departmentSetting = computed(() => {
                return dpaHeaderSetting?.value?.dpaPortalConfiguration?.departmentSetting || {}
            })
            const departmentId = ref(
                userStore.currentDepartment
                    ? userStore.currentDepartment
                    : departmentSetting.value.multiple
                    ? []
                    : undefined
            ) // 当前选中的组织架构id
            const defaultReplaceFields = {
                label: 'label',
                value: 'value',
                children: 'children',
                disable: 'disable'
            }

            const apiTreeData = ref([])
            const apiTreeDataMap = ref(new Map())
            const getTreeDataByApi = () => {
                const { method, url } = departmentSetting.value?.api || {}
                const { link } = departmentSetting.value?.responseData || {}
                if (!method || !url || !link) {
                    return
                }

                axios[method.toLowerCase()](url,{}).then(res => {
                    apiTreeData.value = get(res, link, [])
                })
            }

            // 组织架构树结构信息
            const treeData = computed(() => {
                // 采用固定列表
                if (departmentSetting.value.isStatic) {
                    const staticList = parseJson(departmentSetting.value?.staticList)
                    return !isNullOrUnDef(staticList) && isArray(staticList)? staticList : []
                } else if (apiTreeData.value && !isEmpty(apiTreeData.value)) {
                    let treeDataList = cloneDeep(apiTreeData.value)
                    if(!treeDataList || (!isArray(treeDataList) && !isObject(treeDataList))){
                      return []
                    }
                    if(isObject(treeDataList)){
                      treeDataList = [treeDataList]
                    }
                    const { label, value, children, disable } = replaceFields.value
                    const tempApiTreeDataMap = new Map()
                    recursiveTreeData(treeDataList, children, disable, label, value, tempApiTreeDataMap)
                    // eslint-disable-next-line vue/no-side-effects-in-computed-properties
                    apiTreeDataMap.value = tempApiTreeDataMap
                    return treeDataList
                } else {
                    return []
                }
            })

            const recursiveTreeData = (treeDataList, childrenKey, disableKey, labelKey, valueKey, labelValueMap) => {
                treeDataList.forEach(item => {
                    item['disabled'] = Boolean(item[disableKey])
                    labelValueMap.set(item[valueKey], item[labelKey])
                    if (item[childrenKey] && isArray(item[childrenKey])) {
                        recursiveTreeData(item[childrenKey], childrenKey, disableKey, labelKey, valueKey, labelValueMap)
                    }
                })
            }

            const replaceFields = computed(() => {
                return departmentSetting.value?.isConversion
                    ? {
                          label: departmentSetting.value.conversionConfigLabel,
                          value: departmentSetting.value.conversionConfigValue,
                          children: departmentSetting.value.conversionConfigChildren,
                          disable: departmentSetting.value.conversionConfigDisable
                      }
                    : defaultReplaceFields
            })
            const treeNodeFilterProp = computed(() => {
                return departmentSetting.value?.isConversion
                    ? departmentSetting.value.conversionConfigLabel
                    : defaultReplaceFields.label
            })
            // logo设置
            const dpaLogo = computed(() => {
                return dpaHeaderSetting.value.logoSettings ? dpaHeaderSetting.value.logoSettings : Logo
            })
            const isMultiple = computed(() => {
                return departmentSetting.value?.multiple
            })
            const departmentShow = computed(() => {
                return departmentSetting.value?.show
            })
            const selectedLabels = computed(() => {
                if (departmentId.value && isArray(departmentId.value)) {
                    return departmentId.value.map(item => apiTreeDataMap.value.get(item)).join(' , ')
                } else if (departmentId.value) {
                    return apiTreeDataMap.value.get(departmentId.value)
                } else {
                    return ''
                }
            })
            watch(
                () => props.portalConfiguration,
                value => {
                    dpaHeaderSetting.value = value
                    if (!value?.dpaPortalConfiguration?.departmentSetting?.isStatic) {
                        getTreeDataByApi()
                    }
                },
                {
                    deep: true,
                    immediate: true
                }
            )
            watch(
                () => departmentId.value,
                newDepartmentId => {
                  let departmentIds = getDepartmentId(newDepartmentId, true)
                  userStore.setCurrentDepartment(departmentIds)
                }
            )

            const getDepartmentId = (departmentIds: number | number[] | string | string[] | undefined, hasFolder: boolean) => {
              const resultIds: number[] = []
              recursiveTree(treeData.value, departmentIds, resultIds, hasFolder, false)
              return resultIds
            }

            const recursiveTree = (
                treeData,
                departmentIds: number | number[] | string | string[] | undefined,
                resultId: number[],
                hasFolder: boolean,
                isChild: boolean
            ) => {
              const { value, children } = replaceFields.value
              treeData.forEach(item => {
                const isSelectedNode = isArray(departmentIds)
                    ? departmentIds.includes(item[value])
                    : item[value] === departmentIds
                // 如果是父级是选中状态，子级不需要进一步判断
                if (isChild || isSelectedNode) {
                  // 如果配置的文件夹也需要
                  if (hasFolder) {
                    resultId.push(item[value])
                  } else if (!item[children] || (item[children] && isEmpty(item[children]))) {
                    resultId.push(item[value])
                  }

                  // 如果包括选项有子级，继续递归
                  if (item[children]) {
                    recursiveTree(item[children], departmentIds, resultId, hasFolder, isChild || isSelectedNode)
                  }
                } else if (item[children]) {
                  recursiveTree(item[children], departmentIds, resultId, hasFolder, isChild)
                }
              })
            }
            function init() {
                time.value = getStorageByKey(CURRENT_TIME) || dayjs().format('YYYY.MM.DD')
            }
            // ---------------------------------------------------- 初始化
            init()

            return {
                dpaLogo,
                userImg,
                systemTimeImg,
                time,
                dpaHeaderSetting,
                departmentInfo,
                replaceFields,
                treeNodeFilterProp,
                departmentId,
                popupContainer,
                dropdownIcon,
                showTitle,
                titleStyles,
                treeData,
                Logo,
                departmentShow,
                isMultiple,
                SHOW_PARENT,
                selectedLabels
            }
        }
    })
</script>

<style lang="less" scoped>
    .dpa-header {
      height: 47px;
      line-height: 47px;
      display: flex;
      align-items: center;
      position: relative;
      padding: 0 32px;

      .logo {
        padding-right: 16px;

        img {
          height: 38px;
        }
      }

      .ver {
        width: 1px;
        background: #515f73;
        height: 31px;
      }

      .center-area {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        position: relative;

        .organizational {
          position: absolute;
          left: 16px;
          font-size: 16px;
          color: #192842;

          .@{ant-prefix}-select {
            width: 240px;
            height: 28px;
            font-size: 16px;
            color: #192842;
            display: block;
          }

          :deep(.anticon-caret-down) {
            color: #788397;
          }

          :deep(.@{ant-prefix}-select-selector) {
            background-image: linear-gradient(0deg, #875509 0%, #ffe296 100%);
            border: 0;
            border-radius: 2px;
            font-size: 14px;
          }

          :deep(.@{ant-prefix}-select-multiple) {
            .@{ant-prefix}-select-selection-overflow {
              flex-wrap: nowrap;
              overflow: auto;
              &::-webkit-scrollbar {
                display: none;
              }
              .@{ant-prefix}-select-selection-item {
                background-color: transparent;
                border: 1px solid #192842;
                border-radius: 2px;
                padding: 0 8px;
                font-size: 12px;
                color: #192842;
              }
            }
            .@{ant-prefix}-select-selection-item-remove {
              color: #192842;
              .anticon {
                vertical-align: 0;
              }
            }
          }

          :deep(.@{ant-prefix}-select-arrow) {
            right: 8px;

            .anticon-caret-down {
              color: #020a15;
            }
          }

          :deep(.@{ant-prefix}-select-open) {
            .@{ant-prefix}-select-selector {
              box-shadow: 0 0px 0px;
              border-color: none;
            }
          }

          :deep(.@{ant-prefix}-select-dropdown) {
            width: 189px !important;
            margin-top: 4px;
            background: #0a1629;
            border: 1px solid rgba(255, 215, 126, 0.3);
            border-radius: 2px;
            padding: 4px 0;

            .@{ant-prefix}-select-tree {
              color: #ffffff;
              background: #0a1629;
              padding: 0;

              .@{ant-prefix}-select-tree-list {
                height: 100%;
              }

              .@{ant-prefix}-select-tree-treenode {
                padding: 4px 0;
              }

              .@{ant-prefix}-select-tree-indent-unit {
                width: 16px;
              }

              .@{ant-prefix}-select-tree-switcher .@{ant-prefix}-select-tree-switcher-icon {
                font-size: 12px;
                color: #bcc1c8;
                vertical-align: 4px;
              }

              .@{ant-prefix}-select-tree-treenode:hover,
              .@{ant-prefix}-select-tree-treenode.@{ant-prefix}-select-tree-treenode-selected {
                background: #1f2c48;
              }

              .@{ant-prefix}-select-tree-node-content-wrapper {
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
                color: #ffffff;
                text-align: left;
                font-size: 14px;
                font-family: MicrosoftYaHei;
                line-height: 20px;
                margin: 0;
              }

              .@{ant-prefix}-select-tree-treenode-disabled .@{ant-prefix}-select-tree-node-content-wrapper {
                color: #ffffff80
              }

              .@{ant-prefix}-select-tree-list-holder {
                &::-webkit-scrollbar-track {
                  background: transparent;
                }

                &::-webkit-scrollbar-thumb {
                  border-radius: 5px;
                  background: #ffd77e;
                }
              }

              .@{ant-prefix}-select-tree-node-content-wrapper:hover,
              .@{ant-prefix}-select-tree-node-content-wrapper.@{ant-prefix}-select-tree-node-selected {
                background: transparent;
              }
            }

            .@{ant-prefix}-select-tree-checkbox {
              .@{ant-prefix}-select-tree-checkbox-inner {
                border: 1px solid #788397;
                background-color: transparent;
              }
              &.@{ant-prefix}-select-tree-checkbox-indeterminate .@{ant-prefix}-select-tree-checkbox-inner,
              &.@{ant-prefix}-select-tree-checkbox-checked .@{ant-prefix}-select-tree-checkbox-inner {
                background: #788397;
              }
              &.@{ant-prefix}-select-tree-checkbox-indeterminate
              .@{ant-prefix}-select-tree-checkbox-inner::after {
                width: 7px;
                height: 7px;
                background-color: #fff;
              }
              &.@{ant-prefix}-select-tree-checkbox-checked .@{ant-prefix}-select-tree-checkbox-inner {
                background-color: #788397;
              }
              &.@{ant-prefix}-select-tree-checkbox-disabled .@{ant-prefix}-select-tree-checkbox-inner{
                border: 1px solid #78839780!important;
              }
            }
          }

          :deep(.@{ant-prefix}-select-single.@{ant-prefix}-select-open .@{ant-prefix}-select-selection-item) {
            color: #020a15;
          }
        }
      }

      .title {
        position: absolute;
        left: 50%;
        transform: translate(-50%, 0);
        background-image: linear-gradient(to left, #b6740f, #e8b652 41%, #ffe5a1 92%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        font-weight: 600;
        font-size: 20px;
        font-family: Microsoft YaHei;
      }

      .config {
        display: flex;
        color: #f4dccb;

        .userinfo {
          margin-right: 32px;

          .user-name {
            display: flex;
            align-items: center;

            .prefix-icon {
              margin-right: 8px;
              display: inline-block;
            }
          }

          :deep(.anticon-down) {
            margin-left: 4px;
          }

          :deep(.@{ant-prefix}-dropdown) {
            .@{ant-prefix}-dropdown-menu-item {
              color: #ffffff;
            }

            .@{ant-prefix}-dropdown-menu-item:hover {
              color: #010b19;
            }

            .@{ant-prefix}-dropdown-menu {
              background-color: rgba(28, 56, 94, 0.6);
              border: 1px solid #f4dccb;
              box-shadow: 0 0 15px 0 rgba(13, 18, 30, 0.75);
              border-radius: 4px;
            }
          }
        }

        .time {
          display: flex;
          align-items: center;

          .system-time-icon {
            margin-right: 8px;
          }
        }
      }
    }
</style>
